#pragma once
#include <string>
#include <queue>
#include <utility>
#include "player.h"
#include "hand.h"

class Hand;

//技能类
class Skill {
public:
    enum class Type {
        None = 0,
        Initiative = 01,     //主动
        Passive = 010,   //被动
        Locking = 0100  //锁定
    };

    //阶段
    enum class Stage {
        None = 0,
        Ready = 01, //准备
        Determination = 010,    //判定
        Draw = 0100,    //摸牌
        PlayCord = 01000,   //出牌
        Fold = 010000,  //弃牌
        END = 0100000,  //结束
        Other = 0100000
    };

    //条件
    enum class Condition {
        None = 0,
        InjuryBefore,   //受伤前
        InjuryAfter,    //受伤后
        DeterminationBefore,    //判定前
        DeterminationInjuryAfter,   //判定后
        LoseCard,   //失去牌后
    };

    Skill(std::string  name, std::string  desc, Hand& h, Type type = Type::None, Stage stage = Stage::None, Condition condition = Condition::None): name(std::move(name)), desc(std::move(desc)), hand(h), type(type), stage(stage), condition(condition) {}
    Skill(std::string&& name, std::string&& desc, Hand& h, Type type = Type::None, Stage stage = Stage::None, Condition condition = Condition::None): name(std::move(name)), desc(std::move(desc)), hand(h), type(type), stage(stage), condition(condition) {}
    const Skill& setName(const std::string& x);
    const Skill& setName(std::string&& x);
    [[nodiscard]] const std::string& getName() const;
    const Skill& setDesc(const std::string& x);
    const Skill& setDesc(std::string&& x);
    [[nodiscard]] const std::string& getDesc() const;
    const Skill& setType(Type t);
    [[nodiscard]] Type getType() const;
    const Skill& setStage(Stage s);
    Stage getStage();
    const Skill& setCondition(Condition c);
    Condition getCondition();

    //牌，牌堆
    virtual const Card* exec() = 0;

    //是否有转换属性
    [[nodiscard]] virtual Card::Type isConvert() const;
    //是否有判定属性
    [[nodiscard]] virtual bool isDetermine() const;
    //特定牌触发
    [[nodiscard]] virtual bool isSpecifyCard(Card::Type type) const;
    virtual ~Skill() = default;
private:
    std::string name;
    std::string desc;
    Hand& hand;
    Type type;
    Stage stage;
    Condition condition;
};
